from langchain_ollama import ChatOllama
from langchain.prompts import PromptTemplate
# from langchain.chains import SequentialChain # 不支持LCEL
from langchain_core.runnables import RunnablePassthrough

llm = ChatOllama(
    model="deepseek-r1:8b",
    base_url="http://localhost:11434",  # Ollama 服务地址
    temperature=0.7,  # 创造性程度
    num_predict=1024,  # 最大生成长度
    options={'stop': ['</think>', '</think>']} # 遇到这些标记就停止
)

# chain 1 植物学家定义
template_1 = """你是一个植物学家。给定花的名称和类型，你需要为这种花写一个200字左右的介绍。花名: {name}颜色: {color}植物学家: 这是关于上述花的介绍:"""
prompt_1 = PromptTemplate(input_variables=["name", "color"], template=template_1, output_variables=["introduction"])

chain_1 = prompt_1 | llm 

# chain 2 评论家介绍
template_2 = """你是一个评论家。给定花的介绍，你需要为这种花写一个200字左右的评论。介绍: {introduction}评论家: 这是关于上述花的评论:"""
prompt_2 = PromptTemplate(input_variables=["introduction"], template=template_2, output_variables=["review"])

chain_2 = prompt_2 | llm

# chain 3 自媒体运营
template_3 = """你是一个自媒体运营者。给定花的介绍和评论，你需要为这种花写一个200字左右的自媒体文章。介绍: {introduction}评论: {review}自媒体运营者: 这是关于上述花的自媒体文章:"""
prompt_3 = PromptTemplate(input_variables=["introduction", "review"], template=template_3, output_variables=["article"])

chain_3 = prompt_3 | llm


# chain 组合,SequentialChain 不支持LCEL, 所以用 RunnablePassthrough 实现
# flower_chain = SequentialChain(
#   chains=[chain_1, chain_2, chain_3],
#   input_variables=["name", "color"],
#   output_variables=["introduction", "review", "article"],
#   verbose=True
# )

flower_chain = (
  RunnablePassthrough.assign(introduction = chain_1) |
  RunnablePassthrough.assign(review = chain_2) |
  RunnablePassthrough.assign(article = chain_3)
)

output = flower_chain.invoke({"name": "玫瑰", "color": "黑色"})
print(output)
# {'name': '玫瑰', 'color': '黑色', 'introduction': AIMessage(content='好的，请听我这位植物学家为您解析：\n\n**介绍：黑色玫瑰**\n\n自然界中严格意义上的“纯黑”花卉极为罕见，玫瑰亦不例外。然而，“黑色玫瑰”作为一个广义的术语，通常指的是那些花瓣色彩深邃、近乎黑色或呈现极其浓郁深紫色（这种紫在光线下有时会被误认为黑）的人工培育品种。\n\n这些深色系玫瑰是植物学家和园艺育种家通过精心杂交选育得到的独特品相。它们继承了亲本中强烈的花青素基因，使得花瓣色彩密度极高。例如，著名的“巧克力”或“夜皇后”等品种，其花朵呈现出的深沉紫黑色极为醒目，在适当的光线下几乎达到了黑色的效果。\n\n虽然它们并非真正的黑色，但这些浓色调赋予了玫瑰一种神秘、高贵且略带忧郁的独特美感，并在特定光照和角度下展现出令人惊叹的视觉冲击力。这些也是玫瑰花色谱中非常受欢迎的一部分，体现了人类对自然界色彩创造的热情与努力。', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:8b', 'created_at': '2025-10-16T09:00:39.381185Z', 'done': True, 'done_reason': 'stop', 'total_duration': 47204367750, 'load_duration': 89294875, 'prompt_eval_count': 53, 'prompt_eval_duration': 1049889708, 'eval_count': 527, 'eval_duration': 44239169073, 'model_name': 'deepseek-r1:8b'}, id='run--083c756c-13ff-4e87-ba42-b30ecadf2e69-0', usage_metadata={'input_tokens': 53, 'output_tokens': 527, 'total_tokens': 580}), 'review': AIMessage(content='从植物学的角度来看，“黑色玫瑰”虽然并非自然界严格意义上的纯黑品种，但却是人类智慧与审美的完美结晶。通过精心的杂交选育和基因技术的应用，培育出深邃近乎黑色或浓郁紫黑色的花色是一项令人惊叹的技术成就。\n\n这种深色调玫瑰不仅继承了亲本中强烈的花青素基因，还赋予了玫瑰一种神秘、高贵的独特美感。在适当的光线下，它们几乎达到了真正的黑色效果，给人一种强烈的视觉冲击力和艺术享受。这些花朵的颜色变化也让人们有机会从不同角度感受自然的魅力。\n\n值得一提的是，“黑色玫瑰”的命名也反映出人们对色彩的情感认知——深沉的紫色被形容为巧克力或夜皇后般的忧郁与高贵并存，这种浪漫化的表述本身就是一种文化现象。可以说，在人类对花卉世界的探索中，这些深色系玫瑰代表了我们对自然界极限的一次挑战和突破。\n\n当然，不同人对于“黑色”的感受并不完全一致，有人喜欢其神秘感，也有人更偏爱传统红、黄等亮色调的玫瑰。但无论如何，“黑色玫瑰”作为人类创造力与植物特性结合的艺术品，都值得被赞美和珍视。', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:8b', 'created_at': '2025-10-16T09:01:23.708626Z', 'done': True, 'done_reason': 'stop', 'total_duration': 44317933291, 'load_duration': 99473875, 'prompt_eval_count': 490, 'prompt_eval_duration': 4046260792, 'eval_count': 456, 'eval_duration': 38578548622, 'model_name': 'deepseek-r1:8b'}, id='run--e9b2dc35-84bb-403f-ad70-e3538fdeca6c-0', usage_metadata={'input_tokens': 490, 'output_tokens': 456, 'total_tokens': 946}), 'article': AIMessage(content='好的，请看这篇关于黑色玫瑰的自媒体小文：\n\n# 标题：【探秘】这抹深邃的黑，竟然是“玫瑰”的颜色？！\n\n你见过真正的黑玫瑰吗？还是那仅在特定角度和光线下才显得神秘莫测的深紫？\n\n从植物学的角度来看，“纯黑”花卉极其罕见，严格意义上的黑色玫瑰更是不存在于自然界的。但“黑色玫瑰”这一概念，是人类智慧与审美的结晶！它们其实是通过精心杂交选育出来的人工品种，花瓣继承了亲本中强烈的花青素基因，色彩密度极高，在光线下呈现出近乎黑色或浓郁紫黑的视觉效果。\n\n比如巧克力般丝滑、夜皇后般深邃，这些名字本身就充满了诱惑和神秘感。在对的光线下看它们，那“接近黑色”的魅力足以震撼人心！这不只是颜色的变化，更是人类挑战自然极限的一次突破性尝试，值得我们点赞！\n\n所以，下次你欣赏一朵被称作“黑玫瑰”的花时，记得它背后蕴含的是科学与艺术相结合的故事。🌹☕️🌙', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:8b', 'created_at': '2025-10-16T09:02:23.773791Z', 'done': True, 'done_reason': 'stop', 'total_duration': 60058501125, 'load_duration': 98822209, 'prompt_eval_count': 978, 'prompt_eval_duration': 7966172792, 'eval_count': 578, 'eval_duration': 50054597886, 'model_name': 'deepseek-r1:8b'}, id='run--c6b0d702-85af-42ca-a0ca-f8ac8bd647ae-0', usage_metadata={'input_tokens': 978, 'output_tokens': 578, 'total_tokens': 1556})}